#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2022/2/14 17:11
# @Author  : afraidbenq
# @File    : swagger_reader.py
# @Software: PyCharm
# @Github  : github/afraidbenq
# @Email   : 329189987@qq.com
# @Desc    :
import os

import requests
from ruamel import yaml  # pip install ruamel.yaml dict按yaml格式写入文件
from googletrans import Translator  # pip install 'googletrans==4.0.0rc1' 谷歌翻译的第三方包
from ruamel.yaml import RoundTripLoader, RoundTripDumper
from config import Config
from config.models import TestCase
from common import logger


def merged_yaml_data(yaml_path, api):
    with open(yaml_path, 'r', encoding="utf-8") as file:
        data1 = yaml.load(file, Loader=RoundTripLoader)
    data2 = api
    # 暂时只对用例里data、requestType数据进行处理，保留原始数据，并对新字段进行增量处理
    if len(data1.keys()) > 2:
        logger.warning("单用例文件内存在多个用例")
        return
    data1_data = data1[list(data1.keys())[-1]]['data']
    data2_data = data2[list(data2.keys())[-1]]['data']
    data1_requestType = data1[list(data1.keys())[-1]]['requestType']
    for k, v in data2_data.items():
        if k in data1_data.keys():
            data2[list(data2.keys())[-1]]['data'][k] = data1_data[k]
    data2[list(data2.keys())[-1]]['requestType'] = data1_requestType
    merged_data = {**data1, **data2}
    with open(yaml_path, 'w', encoding="utf-8") as file:
        documents = yaml.dump(merged_data, file, Dumper=RoundTripDumper, allow_unicode=True)


def sync_swagger_doc(project_info, api_doc):

    if "openapi" in api_doc:
        logger.info("openApi3.0")
        for k, v in api_doc.items():
            print(f"{k}:{v}")
        print("--------------------------------")
        # 生成项目目录
        project_name = project_info["project_name"]
        case_data_path = os.path.join(Config.case_data_path, project_name)
        if not os.path.exists(case_data_path):
            os.mkdir(case_data_path)
        # 获取schemas 用于post请求参数如果使用schema，需要在这里面找
        schemas = api_doc["components"]["schemas"]
        # 公共参数
        allureEpic = api_doc["info"]["title"]

        # 遍历所有接口
        for k, v in api_doc["paths"].items():
            api = {"case_common": {"allureEpic": allureEpic,
                                   "allureFeature": None,
                                   "allureStory": None}}
            case_id = 0
            mudule_name = k.split("/")[1]
            logger.info(mudule_name)
            # 生成模块目录
            case_mudule_path = os.path.join(case_data_path, mudule_name)
            if not os.path.exists(case_mudule_path):
                os.mkdir(case_mudule_path)
            logger.info(case_mudule_path)
            # 查询path下原有的文件
            file_list = []
            for file in os.listdir(case_mudule_path):
                if file.endswith('yaml'):
                    file_list.append(file)
            logger.info(file_list)
            for method, operation in v.items():
                case_id += 1
                case_name = "_".join(k.replace("{", "").replace("}", "").split("/")[1:]) + "_0" + str(case_id)
                logger.info(case_name)
                api[case_name] = {}
                allureFeature = operation["tags"][0]
                allureStory = operation["summary"]
                api["case_common"]["allureFeature"] = allureFeature
                api["case_common"]["allureStory"] = allureStory
                api[case_name].update({"projectName": project_name})
                api[case_name].update({"host": "$cache{host}"})
                api[case_name].update({"url": k})
                api[case_name].update({"method": method.upper()})
                api[case_name].update({"detail": operation["operationId"]})
                if "requestBody" in operation:
                    print("使用schemas")
                    api[case_name].update({"headers": {"Content-Type": "application/json; charset=UTF-8",
                                                       "token": "$cache{token}",
                                                       "Cookie": "$cache{Cookie}"}})
                    api[case_name].update({"requestType": "JSON"})
                    key = operation["requestBody"]["content"]["application/json"]["schema"]["$ref"].split("/")[-1]
                    data = schemas[key]["properties"].copy()
                    for k1, v1 in data.items():
                        if v1["type"] == "string":
                            data[k1] = "${{random_en_str()}}"
                        else:
                            data[k1] = None
                else:
                    print("使用params")
                    api[case_name].update({"headers": {"Content-Type": "application/x-www-form-urlencoded",
                                                       "token": "$cache{token}",
                                                       "Cookie": "$cache{Cookie}"}})
                    api[case_name].update({"requestType": "PARAMS"})
                    data = {}
                    if "parameters" in operation:
                        for p in operation["parameters"]:
                            name = p["name"]
                            if p["schema"]["type"] == "string":
                                value = "${{random_en_str()}}"
                            else:
                                value = None
                            data.update({name: value})
                    else:
                        data = {}
                api[case_name].update({"is_run": True})
                api[case_name].update({"data": data})
                api[case_name].update({"dependence_case": False})
                api[case_name].update({"dependence_case_data": None})
                api[case_name].update({"assert": {"status_code": 200}})
                api[case_name].update({"current_request_set_cache": None})
                api[case_name].update({"sql": None})
                api[case_name].update({"teardown": None})
                api[case_name].update({"teardown_sql": None})
            # 生成测试用例yaml数据文件
            yaml_file = f'{"_".join(k.replace("{", "").replace("}", "").split("/")[1:])}.yaml'
            logger.info(yaml_file)
            yaml_path = os.path.join(case_mudule_path, yaml_file)
            logger.info(yaml_path)
            #     # 标记还需要的文件
            #     file_list.remove(yaml_file)
            #     logger.info(file_list)
            #     if not os.path.exists(yaml_path):
            #         with open(yaml_path, "w", encoding="utf-8") as f:
            #             yaml.dump(api, f, Dumper=yaml.RoundTripDumper, allow_unicode=True)
            #     else:
            #         merged_yaml_data(yaml_path, api)
            # # 删除多余接口文件
            # if file_list:
            #     logger.info(f'旧版多余接口文件{file_list}')
            #     for file in file_list:
            #         file_path = os.path.join(case_mudule_path, file)
            #         logger.info(file_path)
            #         os.remove(file_path)


    elif "swagger" in api_doc:
        logger.info("swagger2.0")
        for k, v in api_doc.items():
            print(f"{k}:{v}")
        print("--------------------------------")
        # 生成项目目录
        project_name = project_info["project_name"]
        case_data_path = os.path.join(Config.case_data_path, project_name)
        if not os.path.exists(case_data_path):
            os.mkdir(case_data_path)




def update_config(project_info):
    # 写入到config\*_env\*.yaml文件
    yamlpath = os.path.join(Config.config_path, Config.env, f"{project_info['projectName']}.yaml")
    with open(yamlpath, "w", encoding="utf-8") as f:
        # Dumper=yaml.RoundTripDumper去除字典的嵌套，真正yaml格式, allow_unicode=True允许直接显示中文,中文字符不会被转码
        yaml.dump(project_info, f, Dumper=yaml.RoundTripDumper, allow_unicode=True)


if __name__ == '__main__':
    from common import logger
    # 输入项目名生成测试用例yaml文件
    # project_name = "pay"
    # project_name = "icbc"
    project_name = "example_project"
    env = "test"
    project_info = eval(f"Config.project['{project_name}']")
    logger.info(project_info)
    api_docs_url = project_info["api_docs_url"]
    r = requests.get(api_docs_url)
    api_doc = r.json()
    logger.info(api_doc)
    # 同步项目最新接口文档的数据，生成或更新yaml文件
    # sync_swagger_doc(project_info, api_doc)
    from swagger_parser import SwaggerParser
    #将Swagger文档转换成python对象
    parser = SwaggerParser(swagger_dict=api_doc)  # Init with file
